package com.master_jpeg.img;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RasterFormatException;


public class ImagePanel extends JPanel {

    private int xImg, yImg, wImg, hImg;
    private Point2D press = new Point2D.Double(0, 0);
    private boolean pressedBtn = false;
    private Rectangle2D rect = new Rectangle2D.Double();
    private double zoom = 1;
    private static  BufferedImage image;
    private AffineTransform at = new AffineTransform(); // identity transform
    private ImagePanel container;

    public ImagePanel(BufferedImage image) {
        this.image = image;

        zoom = 1;
        xImg = 0;
        yImg = 0;
        wImg = image.getWidth();
        hImg = image.getHeight();
        setPreferredSize(new Dimension(wImg, hImg));

        this.addMouseWheelListener(new MouseWheelListener() {
            //добавляем обработчик событий который слушает колёсико мышки, ну и изменяет размер картинки
            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                if (e.getWheelRotation() == 1) {
                    zoom += 0.1;
                } else {
                    zoom -= 0.1;
                }
                at = AffineTransform.getScaleInstance(zoom, zoom);
                int width = (int) (zoom * wImg);
                int height = (int) (zoom * hImg);
                setPreferredSize(new Dimension(width, height));
                repaint();
            }
        });

        this.addMouseListener(new MouseAdapter()
        {

            //записываем первую точку где кликается мышкой и начинается Drag&Dpop
            @Override
            public void mousePressed(MouseEvent e) {
                press = e.getPoint();
                pressedBtn = true;
            }
            /**Метод берет параметры выделеного прямоугольника и перерисовывает тлько выделеную часть картнки
             * Т.к. картинка может менять свои размеры(когда крутишь колесико), то выделеные координаты не соответсвуют
             * координатам картинки. Потому мы делим на zoom
             * Блоки if...else - если бы их не было, тогда когда прямоугольник был больше отрисованной картинки,
             * то отрисовывалась уже удаленная часть картинки. В общем не знаю как обьяснить, удали их сам поймешь.
             **/
            @Override
            public void mouseReleased(MouseEvent e) {
                pressedBtn = false;
                if ((int) rect.getWidth() != 0 && (int) rect.getHeight() != 0) {
                    xImg += rect.getX() / zoom;
                    yImg += rect.getY() / zoom;
                    if ((rect.getX() + rect.getWidth()) <= wImg) {
                        wImg = (int) (rect.getWidth() / zoom);
                    } else {
                        wImg = (int)((wImg - (int)rect.getX()) / zoom);
                    }
                    if ((rect.getY() + rect.getHeight()) <= hImg) {
                        hImg = (int) (rect.getHeight() / zoom);
                    } else {
                        hImg = (int)((hImg - (int)rect.getY()) / zoom);
                    }
                    repaint();


                }
            }
        });

        this.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                double x, y, w, h;

                if (e.getX() > (int) press.getX()) {
                    x = press.getX();
                    w = (double) e.getX() - press.getX();
                } else {
                    x = (double) e.getX();
                    w = press.getX() - (double) e.getX();
                }

                if (e.getY() > (int) press.getY()) {
                    y = press.getY();
                    h = (double) e.getY() - press.getY();
                } else {
                    y = (double) e.getY();
                    h = press.getY() - (double) e.getY();
                }
                setRect(new Rectangle2D.Double(x, y, w, h));
            }
        });

    }

    public void setRect(Rectangle2D rect) {
        this.rect = rect;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.transform(at);
        if (image != null) {
            g.drawImage(image,0, 0, (int)(wImg*zoom), (int)(hImg*zoom),
                    xImg,
                    yImg,
                    xImg + wImg,
                    yImg + hImg,
                    null);
            if (pressedBtn) {
                g2.draw(rect);
            }

        }
    }

    public ImagePanel getContainer() {
        return container;
    }

    public void setContainer(ImagePanel container) {
        this.container = container;
    }
}